package org.qiyu.live.im.core.server.service.impl;

import com.alibaba.fastjson.JSON;
import jakarta.annotation.Resource;
import org.apache.rocketmq.client.producer.MQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.idea.qiyu.live.framework.redis.starter.key.IMCoreServerProviderCacheKeyBuilder;
import org.qiyu.live.im.core.server.service.MsgAckServiceHandler;
import org.qiyu.live.im.dto.ImMsgBody;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import static org.qiyu.live.common.interfaces.topic.ImCoreServerProviderTopicNames.QIYU_LIVE_IM_ACK_MSG_TOPIC;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: sfx
 * Date: 2023-10-19
 * Time: 20:20
 */
@Service
public class MsgAckServiceHandlerServiceImpl implements MsgAckServiceHandler {

    // 引入redis
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private IMCoreServerProviderCacheKeyBuilder cacheKeyBuilder;

    @Resource
    private MQProducer mqProducer;

    private final Logger LOGGER = LoggerFactory.getLogger(MsgAckServiceHandlerServiceImpl.class);


    /**
     * 当客户端收到了对方的ack的时候,我们就要把消息从redis中删除
     *
     * @param msgBody 消息
     */
    @Override
    public void doMsgAck(ImMsgBody msgBody) {
        redisTemplate.opsForHash().delete(cacheKeyBuilder.
                buildImAckKey(msgBody.getUserId(), msgBody.getAppId()), msgBody.getMessageId());
    }

    /**
     * IM推送给客户端消息的时候,要在redis中记录一下ack,确保我们消息到达了客户端
     *
     * @param msgBody 消息
     * @param times   重试次数
     */
    @Override
    public void recordMsgAck(ImMsgBody msgBody, int times) {
        redisTemplate.opsForHash().put(cacheKeyBuilder.
                buildImAckKey(msgBody.getUserId(), msgBody.getAppId()), msgBody.getMessageId(), times);
    }

    /**
     * 获取到重试次数(重试看一看ack记录有没有在redis中删除)
     *
     * @param msgBody 消息
     * @return 返回重试次数
     */
    @Override
    public int getRetryTimes(ImMsgBody msgBody) {
        Object times = redisTemplate.opsForHash().get(cacheKeyBuilder.
                buildImAckKey(msgBody.getUserId(), msgBody.getAppId()), msgBody.getMessageId());
        if (times == null) {
            return -1;
        }
        return (int) times;
    }

    /**
     * 发送延迟消息
     *
     * @param msgBody 消息
     */
    @Override
    public void sendDelayMessage(ImMsgBody msgBody) {
        Message message = new Message();
        message.setTopic(QIYU_LIVE_IM_ACK_MSG_TOPIC);
        message.setBody(JSON.toJSONBytes(msgBody));
        //延迟时间为5s
        message.setDelayTimeLevel(2);
        try {
            SendResult sendResult = mqProducer.send(message);
            LOGGER.info("[MsgAckHandlerImpl] msgBody is {} , sendResult is {} ", JSON.toJSONString(msgBody), sendResult);
        } catch (Exception e) {
            // 记录一下异常
            LOGGER.error("[MsgAckHandlerImpl] 发送消息异常 exception is ", e);
        }
    }
}